/**XMLHttpRequest对象（过时产物，现代开发中还是使用fetch） */
// 创建XMLHttpRequest对象：
var xhr = new XMLHttpRequest();
// 设置请求的方法、URL和是否异步：

xhr.open(method, url, async);
// method：请求的方法，如GET、POST等。
// url：请求的URL。
// async：是否异步，默认为true。

// 设置请求头（可选）：
xhr.setRequestHeader(header, value);
// header：请求头的名称。
// value：请求头的值。

// 注册事件处理程序：
xhr.onload = function () {
    // 请求成功完成时的处理代码
};

xhr.onerror = function () {
    // 请求发生错误时的处理代码
};
// onload：请求成功完成时触发的事件。
// onerror：请求发生错误时触发的事件

// 发送请求：
xhr.send(data);
// data：要发送的数据，仅在POST请求中使用。
// 处理响应：

// 在xhr.onload事件处理程序中，可以通过xhr对象的属性来获取响应的数据和状态信息，例如：
var responseText = xhr.responseText; // 响应的文本数据
var status = xhr.status; // 响应的状态码
var statusText = xhr.statusText; // 响应的状态文本
// 需要注意的是，XHR也支持异步请求，可以通过设置xhr对象的async属性为true来实现。在异步请求中，可以使用回调函数或Promise来处理响应。

/**http头部 */

/*
 请求头部
Accept：指定客户端能够接收的响应类型。
Accept-Encoding：指定客户端能够接收的编码方式。
Cache-Control：指定请求和响应的缓存机制。
Cookie：指定客户端的Cookie。
User-Agent：指定客户端的浏览器类型和版本。
响应头部
Content-Type：指定响应的MIME类型。
Content-Encoding：指定响应的编码方式。
Content-Length：指定响应的长度。
Set-Cookie：指定服务器发送的Cookie。
Server：指定服务器的类型和版本。
通用头部
Connection：指定连接的管理方式。
Date：指定消息的创建时间。
Via：指定代理服务器的信息。
 */

/**FormData类型 */
// 需要注意的是，当使用FormData发送请求时，浏览器会自动设置适当的Content-Type头部，并对数据进行适当的编码和格式化。
// FormData还提供了其他一些方法，如delete()用于删除字段，set()用于更新字段的值等。
// 使用FormData可以简化处理表单数据的过程，并且支持文件上传等功能。它在处理AJAX请求时非常有用，特别是在需要上传文件或处理复杂表单数据的情况下。

// 创建一个FormData对象：
var formData = new FormData();

// 添加表单字段：
formData.append(name, value);
// name：字段的名称。
// value：字段的值。

// 可以多次调用append()方法来添加多个字段。
// 添加文件字段：
formData.append(name, file, filename);

/**超时 */
// 在网络请求、异步操作或长时间运行的任务中，设置超时是一种常用的机制，以避免无限等待或阻塞其他操作。
// 在网络请求中，超时可以用来控制请求的最长等待时间，如果在指定的时间内没有收到响应，可以中断请求并进行错误处理。
// 在JavaScript中，可以使用XMLHttpRequest或Fetch API来设置超时。
// 使用XMLHttpRequest时，可以通过设置timeout属性来指定超时时间（单位为毫秒）：

var xhr = new XMLHttpRequest();
xhr.timeout = 5000; // 设置超时时间为5秒
xhr.ontimeout = function () {
    // 超时处理代码
};
xhr.open('GET', url, true);
xhr.send();
// 使用Fetch API时，可以使用setTimeout()函数来模拟超时，然后通过AbortController来取消请求：
var controller = new AbortController();
var signal = controller.signal;
setTimeout(function () {
    controller.abort(); // 取消请求
}, 5000); // 设置超时时间为5秒

fetch(url, { signal })
    .then(function (response) {
        // 处理响应
    })
    .catch(function (error) {
        if (error.name === 'AbortError') {
            // 超时处理代码
        } else {
            // 其他错误处理代码
        }
    });


/**进度事件 */
//   进度事件（Progress Events）是在进行长时间运行的操作或异步操作时，用于跟踪操作进度的事件。
//   它们提供了一种机制，可以在操作进行过程中获取操作的当前状态、完成百分比、已传输的数据量等信息。
//   在JavaScript中，常见的进度事件包括：
//   loadstart：在操作开始时触发，表示操作已经开始。
//   progress：在操作进行过程中触发，用于获取操作的当前状态和进度信息。
//   load：在操作成功完成时触发，表示操作已经完成。
//   error：在操作发生错误时触发，表示操作失败。
//   abort：在操作被中断时触发，表示操作被取消。
//   这些事件通常与异步操作（如XMLHttpRequest、Fetch API、File API等）一起使用。以下是一个使用XMLHttpRequest的示例，展示如何使用进度事件来跟踪文件上传的进度：
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
//进度条
xhr.upload.addEventListener('progress', function (event) {
    if (event.lengthComputable) {
        var percentComplete = (event.loaded / event.total) * 100;
        console.log('上传进度：' + percentComplete.toFixed(2) + '%');
    }
});

xhr.upload.addEventListener('load', function () {
    console.log('上传完成');
});

xhr.upload.addEventListener('error', function () {
    console.log('上传出错');
});

xhr.upload.addEventListener('abort', function () {
    console.log('上传被取消');
});

xhr.send(formData);

/**跨源资源共享 */

// 跨源资源共享（Cross-Origin Resource Sharing，简称CORS）是一种机制，用于在浏览器中处理跨域请求。
// 在Web开发中，浏览器执行同源策略，即限制从一个源加载的文档或脚本如何与来自其他源的资源进行交互。
// CORS允许服务器在响应中设置一些特定的HTTP头，以授权其他域的浏览器访问其资源。

// CORS的工作原理如下：

// 浏览器发送跨域请求时，会在请求头中添加一个Origin字段，表示请求的源。
// 服务器接收到请求后，检查Origin字段，确定是否允许该源访问资源。
// 如果服务器允许该源访问资源，会在响应头中添加一些CORS相关的头信息，如Access-Control-Allow-Origin，指定允许访问的源。
// 浏览器收到响应后，会检查响应头中的CORS相关信息，如果与请求的源匹配，则浏览器允许访问响应的数据。
// 要启用CORS，服务器需要在响应头中设置一些特定的头信息。以下是一些常用的CORS头信息：

// Access-Control-Allow-Origin：指定允许访问资源的源。可以是具体的域名，也可以是通配符*，表示允许任何源访问资源。
// Access-Control-Allow-Methods：指定允许的HTTP方法，如GET、POST等。
// Access-Control-Allow-Headers：指定允许的请求头。
// Access-Control-Allow-Credentials：指定是否允许发送身份凭证（如cookies、HTTP认证等）。
// Access-Control-Max-Age：指定预检请求（OPTIONS请求）的有效期，以减少对服务器的频繁请求。
// 以下是一个使用CORS的示例：
// 服务器端设置响应头
response.setHeader('Access-Control-Allow-Origin', 'https://example.com');
response.setHeader('Access-Control-Allow-Methods', 'GET, POST');
response.setHeader('Access-Control-Allow-Headers', 'Content-Type');
response.setHeader('Access-Control-Allow-Credentials', 'true');

// 客户端发起跨域请求
fetch('https://api.example.com/data', {
    method: 'GET',
    credentials: 'include'
})
    .then(function (response) {
        // 处理响应
    })
    .catch(function (error) {
        // 处理错误
    });
// 在上述示例中，服务器设置了允许https://example.com域名访问资源，并允许使用GET和POST方法。

// 客户端使用Fetch API发起跨域请求，并设置了credentials选项为include，以允许发送身份凭证。

// 通过使用CORS，服务器可以控制哪些域名可以访问其资源，从而增加了Web应用程序的安全性和灵活性。


/**Fetch */

// 它返回一个Promise对象，可以使用Promise的链式调用来处理响应数据。
// 以下是一个使用Fetch API发送GET请求的示例：
fetch('https://api.example.com/data')
    .then(function (response) {
        if (response.ok) {
            return response.json(); // 将响应数据解析为JSON格式
        } else {
            throw new Error('请求失败');
        }
    })
    .then(function (data) {
        // 处理响应数据
        console.log(data);
    })
    .catch(function (error) {
        // 处理错误
        console.log(error);
        //   });
        // 在上述示例中，使用Fetch API发送一个GET请求到https://api.example.com/data，
        // 然后通过Promise的链式调用处理响应数据。首先检查响应的状态码，如果是200（即OK），则将响应数据解析为JSON格式；否则，抛出一个错误。
        // 最后，处理解析后的数据或捕获错误。
        // Fetch API还支持设置请求头、请求体和请求参数等。例如，可以使用headers选项设置请求头，使用method选项设置请求方法，使用body选项设置请求体等。
        fetch('https://api.example.com/data', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ name: 'John', age: 30 })
        })
            .then(function (response) {
                // 处理响应
            })
            .catch(function (error) {
                // 处理错误
            });
    })
// 在上述示例中，发送一个POST请求，设置请求头为Content-Type: application/json，并将请求体设置为一个包含name和age属性的JSON对象。

